package com.itlong.cloud.controller.finance;

import com.itlong.cloud.POJO.DTO.operate.OperateWithdrawPageDTO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.operate.OperateWithdrawVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.FileCatalogEnum;
import com.itlong.cloud.enumerate.IsTimeoutEnum;
import com.itlong.cloud.enumerate.TradeStatusEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.OperateErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.paymenthub.IOperateWithdrawServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <desc>
 * 运营-财务管理模块-财务提现审核主控制器.
 * </desc>
 *
 * @createDate 2018/9/20
 */
@RestController
@RequestMapping("/finance")
@RefreshScope
public class OperateWithdrawController {

    private static final Logger LOG = LoggerFactory.getLogger(OperateWithdrawController.class);


    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Autowired
    IOperateWithdrawServiceClient iWithdrawServiceClient;

    /**
     * <desc>
     *      财务提现审核信息分页查询
     * <desc/>
     *
     * @param operateWithdrawPageDTO 分页查询参数
     * @return
     * @author Qiang.S
     * @createDate 2018-09-20
     */
    @ResponseBody
    @AuthAccessRequired
    @RequestMapping(path = "/withdraw/getWithdrawInfoPage", method = RequestMethod.POST)
    public Object getWithdrawInfoPage(OperateWithdrawPageDTO operateWithdrawPageDTO){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateWithdrawPageDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateWithdrawPageDTO.class,request);
            //请求对象不能为空
            if(null == operateWithdrawPageDTO){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),iWithdrawServiceClient.getWithdrawInfoPage(operateWithdrawPageDTO));
        }catch (Exception e){
            throw new DataAccessException("【运营_财务管理_财务提现审核信息查询getWithdrawInfoPage】财务提现审核信息查询失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      审批拒绝
     * <desc/>
     *
     * @param cashIds 提现记录ID,逗号分隔
     * @return
     * @author Qiang.S
     * @createDate 2018-09-20
     */
    @ResponseBody
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.WITHDRAW_REFUSE_DESC)
    @RequestMapping(path = "/withdraw/refuse", method = RequestMethod.POST)
    public Object refuse(String cashIds,String myUserName){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            cashIds=request.getAttribute("cashIds")==null?null:request.getAttribute("cashIds").toString();
            myUserName=request.getAttribute("myUserName")==null?null:request.getAttribute("myUserName").toString();
            ///判断项目编号
            if(StringUtils.isBlank(cashIds)){
                return new MessageVO(OperateErrorCodeEnum.REFUSE_CASHIDS_EMPTY_ERR.getErrorCode());
            }
            iWithdrawServiceClient.refuse(cashIds,myUserName);
            messageVO = new MessageVO(cashIds,BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【运营_财务管理_审批拒绝refuse】审批拒绝失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      修改备注
     * <desc/>
     *
     * @param cashId 提现记录ID
     * @param remark 备注
     * @return
     * @author Qiang.S
     * @createDate 2018-09-20
     */
    @ResponseBody
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.WITHDRAW_UPDATE_REMARK_DESC)
    @RequestMapping(path = "/withdraw/updateRemark", method = RequestMethod.POST)
    public Object updateRemark(String cashId, String remark){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            cashId=request.getAttribute("cashId")==null?null:request.getAttribute("cashId").toString();
            remark=request.getAttribute("remark")==null?"":request.getAttribute("remark").toString();
            //判断提现记录ID
            if(StringUtils.isBlank(cashId)){
                return new MessageVO(OperateErrorCodeEnum.REFUSE_CASHIDS_EMPTY_ERR.getErrorCode());
            }
            iWithdrawServiceClient.updateRemark(cashId, remark);
            messageVO = new MessageVO(cashId,BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【运营_财务管理_修改备注updateRemark】修改备注失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      修改状态
     * <desc/>
     *
     * @param cashId 提现记录ID
     * @param tradeStatus 3提现成功 4提现失败
     * @return
     * @author Qiang.S
     * @createDate 2018-09-20
     */
    @ResponseBody
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.WITHDRAW_UPDATE_STATUS_DESC)
    @RequestMapping(path = "/withdraw/updateTradeStatus", method = RequestMethod.POST)
    public Object updateTradeStatus(String cashId,String tradeStatus){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            cashId=request.getAttribute("cashId")==null?null:request.getAttribute("cashId").toString();
            tradeStatus=request.getAttribute("tradeStatus")==null?null:request.getAttribute("tradeStatus").toString();
            //判断提现记录ID
            if(StringUtils.isBlank(cashId)){
                return new MessageVO(OperateErrorCodeEnum.REFUSE_CASHIDS_EMPTY_ERR.getErrorCode());
            }
            //判断状态
            if(StringUtils.isBlank(tradeStatus)){
                return new MessageVO(OperateErrorCodeEnum.REFUSE_CASHIDS_EMPTY_ERR.getErrorCode());
            }
            //判断状态是否在范围内
            if(!"3".equals(tradeStatus) && !"4".equals(tradeStatus)){
                return new MessageVO(OperateErrorCodeEnum.REFUSE_TRADSTATUS_ERR.getErrorCode());
            }
            iWithdrawServiceClient.updateTradeStatus(cashId, tradeStatus);
            messageVO = new MessageVO(cashId,BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【运营_财务管理_修改状态updateTradStatus】修改状态失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      系统财务汇总
     * <desc/>
     *
     * @return
     * @author Qiang.S
     * @createDate 2018-09-20
     */
    @ResponseBody
    @AuthAccessRequired
    @RequestMapping(path = "/withdraw/getFinaceInfo", method = RequestMethod.POST)
    public Object getFinaceInfo(){
        MessageVO messageVO;
        try {
            //第三方支付金额  资金变动明细表  微信结算的 最后一条 交易后金额
            //物业未提现 项目表 sum所有项目的可提现金额
            //物业已提现 物业提现记录表 sum提现金额   处理中和提现成功状态
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),iWithdrawServiceClient.getFinaceInfo());
        }catch (Exception e){
            throw new DataAccessException("【运营_财务管理_系统财务汇总getFinaceInfo】系统财务汇总失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      导出EXCLE
     * <desc/>
     *
     * @return
     * @author Qiang.S
     * @createDate 2018-09-20
     */
    @ResponseBody
    @AuthAccessRequired
    @RequestMapping(path = "/withdraw/exportExcle", method = RequestMethod.POST)
    public Object exportExcle(OperateWithdrawPageDTO operateWithdrawPageDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateWithdrawPageDTO=HttpProtocolUtil.parseRequestParamToDTO(OperateWithdrawPageDTO.class,request);
            List<OperateWithdrawVO> list = iWithdrawServiceClient.getWithdrawInfoForExcle(operateWithdrawPageDTO);
            if (list.size() == 0) {
                return new MessageVO(PropertyErrorCodeEnum.EXPORT_DATA_EMPTY_ERR.getErrorCode());
            }
            String[] title = {"序号","项目编号","项目名称","物业名称","提现银行","卡号","提现金额（¥）","手续费（¥）","提交时间","审批时间","是否超时","状态","审批人","备注"};
            short rowHeight= 420;
            //创建excel工作簿
            HSSFWorkbook workbook=new HSSFWorkbook();
            //创建工作表sheet并设置简单格式
            HSSFSheet sheet=workbook.createSheet();
            sheet.setDefaultColumnWidth(15);
            //创建第一行
            HSSFRow row=sheet.createRow(0);
            row.setHeight(rowHeight);
            HSSFCell cell=null;
            //插入第一行数据的表头
            for (int i = 0; i < title.length; i++) {
                cell = row.createCell(i);
                cell.setCellValue(title[i]);
            }
            //写入数据
            for (int index = 0; index < list.size(); index++) {
                OperateWithdrawVO vo = list.get(index);
                int rowIndex = index + 1; // 第一行已为标题行
                HSSFRow dataRow = sheet.createRow(rowIndex);
                dataRow.setHeight(rowHeight);
                HSSFCell noteCell = dataRow.createCell(0);
                noteCell.setCellValue(rowIndex);
                noteCell = dataRow.createCell(1);
                noteCell.setCellValue(vo.getProjectId());
                noteCell = dataRow.createCell(2);
                noteCell.setCellValue(vo.getProjectName());
                noteCell = dataRow.createCell(3);
                noteCell.setCellValue(vo.getPropertyName());
                noteCell = dataRow.createCell(4);
                noteCell.setCellValue(vo.getOpenBankName());
                noteCell = dataRow.createCell(5);
                if (vo.getBankCardNo() != null && vo.getBankCardNo().length() >= 4) {
                    String replaceStr = "";
                    for (int i=0 ;i<vo.getBankCardNo().length()-4;i++) {
                        replaceStr+="*";
                    }
                    noteCell.setCellValue(replaceStr+vo.getBankCardNo().substring(
                            vo.getBankCardNo().length()-4,vo.getBankCardNo().length()));
                } else {
                    noteCell.setCellValue(vo.getBankCardNo());
                }
                noteCell = dataRow.createCell(6);
                noteCell.setCellValue(vo.getAmount());
                noteCell = dataRow.createCell(7);
                noteCell.setCellValue(vo.getHandlingFee());
                noteCell = dataRow.createCell(8);
                noteCell.setCellValue(vo.getCreateTime());
                noteCell = dataRow.createCell(9);
                noteCell.setCellValue(vo.getUpdateTime());
                noteCell = dataRow.createCell(10);
                noteCell.setCellValue(IsTimeoutEnum.getDescription(Integer.parseInt(vo.getIsTimeout())));
                noteCell = dataRow.createCell(11);
                noteCell.setCellValue(TradeStatusEnum.getDescription(Integer.parseInt(vo.getTradeStatus())));
                noteCell = dataRow.createCell(12);
                noteCell.setCellValue(vo.getChecker());
                noteCell = dataRow.createCell(13);
                noteCell.setCellValue(vo.getRemark());
            }
            String fileName = String.format("%s_OperateWithdrawInfo_%s.xls",
                    operateWithdrawPageDTO.getProjectId(),
                    DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS"));
            fileName = URLEncoder.encode(fileName, "UTF-8");
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            workbook.write(os);
            byte[] content = os.toByteArray();
            InputStream exportFileStream = new ByteArrayInputStream(content);
            String exportFileUrl = uploadFile(exportFileStream,fileName);
            if (StringUtils.isBlank(exportFileUrl)){
                return new MessageVO(PropertyErrorCodeEnum.PROJECT_EXPORT_FILE_SAVE_ERR.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), (Object) exportFileUrl);
        } catch (Exception e) {
            throw new DataAccessException("【运营_财务管理】导出提现审核信息表单失败",e);
        }
    }

    /**
     * <desc>
     *      财务提现审核明细查询
     * <desc/>
     *
     * @param cashId 提现记录ID
     * @return
     * @author Qiang.S
     * @createDate 2018-09-27
     */
    @ResponseBody
    @RequestMapping(path = "/withdraw/getWithdrawDetail", method = RequestMethod.POST)
    public Object getWithdrawDetail(String cashId){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            cashId=request.getAttribute("cashId")==null?null:request.getAttribute("cashId").toString();
            //判断提现记录ID
            if(StringUtils.isBlank(cashId)){
                return new MessageVO(OperateErrorCodeEnum.REFUSE_CASHIDS_EMPTY_ERR.getErrorCode());
            }
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),iWithdrawServiceClient.getWithdrawDetail(cashId));
        }catch (Exception e){
            throw new DataAccessException("【运营_财务管理_修改状态updateTradStatus】修改状态失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @param fileName 文件名称
     * @return 文件上传成功后会返回Url,否则返回空
     * @author Jiaqi.X
     * @createDate 2018/08/17
     */
    private String uploadFile(InputStream inputStream, String fileName) throws IOException {
        String fileUrl = "";
        String fileType = StringHandlerUtil.copySubStr(fileName, fileName.lastIndexOf('.') + 1, fileName.length());
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                fileType,
                FILE_ACCESS_URL,
                FileCatalogEnum.PROPERTY_METER_INFO_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (returnCode == false){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }

}